package org.light.generator;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Writeable;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.exception.ValidateException;
import org.light.utils.WriteableUtil;

public class PDFUtilGenerator extends Generator{
	public PDFUtilGenerator(){
		super();
		super.fileName = "pdf_util.rs";
	}

	@Override
	public StatementList generateStatementList() throws ValidateException {
		List<Writeable> sList = new ArrayList<Writeable>();
		long serial = 1000L;
		sList.add(new Statement(1000L,0,"extern crate printpdf;"));
		sList.add(new Statement(2000L,0,"extern crate image;"));
		sList.add(new Statement(3000L,0,""));
		sList.add(new Statement(4000L,0,"use printpdf::*;"));
		sList.add(new Statement(7000L,0,"use std::fs::File;"));
		sList.add(new Statement(22000L,0,"use std::iter::FromIterator;"));
		sList.add(new Statement(23000L,0,""));
		sList.add(new Statement(25000L,0,""));
		sList.add(new Statement(26000L,0,"pub fn export_pdf_with_images(sheet_name:String, headers:Vec<String>,"));
		sList.add(new Statement(27000L,2,"contents:Vec<Vec<String>>, is_images:Vec<bool>)->Vec<u8>{"));
		sList.add(new Statement(28000L,1,"println!(\"Inside pdf export!\");"));
		sList.add(new Statement(29000L,1,"let mut page_width = 210.0;"));
		sList.add(new Statement(30000L,1,"let mut page_height = 297.0;"));
		sList.add(new Statement(31000L,1,"let mut pagesize = 10;"));
		sList.add(new Statement(32000L,1,"if Vec::len(&headers) > 8 {"));
		sList.add(new Statement(33000L,2,"page_width = 297.0;"));
		sList.add(new Statement(34000L,2,"page_height = 210.0;"));
		sList.add(new Statement(35000L,2,"pagesize = 5;"));
		sList.add(new Statement(36000L,1,"}"));
		sList.add(new Statement(37000L,1,"let (doc, page1, layer1) = PdfDocument::new(\"PDF export\", Mm(page_width), Mm(page_height), \"Layer 1\");"));
		sList.add(new Statement(38000L,1,"let font = doc.add_external_font(File::open(\"./template/fonts/msyh.ttf\").unwrap()).unwrap();"));
		sList.add(new Statement(39000L,1,""));
		sList.add(new Statement(40000L,1,"let mut pageindex = 0;"));
		sList.add(new Statement(41000L,1,"let records_count = Vec::len(&contents);"));
		sList.add(new Statement(42000L,1,"while pageindex * pagesize < records_count{"));
		sList.add(new Statement(43000L,2,"if pageindex == 0{"));
		sList.add(new Statement(44000L,3,"let current_layer = doc.get_page(page1).get_layer(layer1);"));
		sList.add(new Statement(45000L,3,"let mut pageend = (pageindex+1) * pagesize;"));
		sList.add(new Statement(46000L,3,"if pageend>records_count {pageend = records_count;}"));
		sList.add(new Statement(47000L,3,"write_header_row(font.clone(),current_layer.clone(),page_width.clone(),page_height.clone(),headers.clone(),is_images.clone());"));
		sList.add(new Statement(48000L,3,"write_content_rows(font.clone(),current_layer,page_width.clone(),page_height.clone(),contents[pageindex * pagesize..pageend].to_vec(),is_images.clone());"));
		sList.add(new Statement(49000L,2,"}else {"));
		sList.add(new Statement(50000L,3,"let (pagen, layern) = doc.add_page(Mm(page_width), Mm(page_height),\"Layer \".to_owned()+&pageindex.to_string());"));
		sList.add(new Statement(51000L,3,"let current_layer = doc.get_page(pagen).get_layer(layern);"));
		sList.add(new Statement(52000L,3,"let mut pageend = (pageindex+1) * pagesize;"));
		sList.add(new Statement(53000L,3,"if pageend>records_count {pageend = records_count;}"));
		sList.add(new Statement(54000L,3,"write_header_row(font.clone(),current_layer.clone(),page_width.clone(),page_height.clone(),headers.clone(),is_images.clone());"));
		sList.add(new Statement(55000L,3,"write_content_rows(font.clone(),current_layer,page_width.clone(),page_height.clone(),contents[pageindex * pagesize..pageend].to_vec(),is_images.clone());"));
		sList.add(new Statement(56000L,2,"}"));
		sList.add(new Statement(57000L,2,"pageindex += 1;"));
		sList.add(new Statement(58000L,1,"}"));
		sList.add(new Statement(59000L,1,"doc.save_to_bytes().unwrap()"));
		sList.add(new Statement(60000L,0,"}"));
		sList.add(new Statement(61000L,0,""));
		sList.add(new Statement(62000L,0,"fn write_header_row(font:IndirectFontRef,layer:PdfLayerReference, page_width:f64,page_height:f64,headers:Vec<String>, is_images:Vec<bool>){"));
		sList.add(new Statement(63000L,1,"let neat_width = page_width - 20.0;"));
		sList.add(new Statement(64000L,1,"let neat_height = page_height - 10.0;"));
		sList.add(new Statement(65000L,1,"let col_width = neat_width/(Vec::len(&headers) as f64);"));
		sList.add(new Statement(66000L,1,"let row_height = (page_height-20.0)/11.0;"));
		sList.add(new Statement(67000L,1,"println!(\"col_width{}:row_height{}\",col_width,row_height);"));
		sList.add(new Statement(68000L,1,"let outline_color = Color::Rgb(Rgb::new(1.0, 0.0, 0.0, None));"));
		sList.add(new Statement(69000L,1,"let innerline_color = Color::Rgb(Rgb::new(0.0, 0.0, 0.0, None));"));
		sList.add(new Statement(70000L,1,""));
		sList.add(new Statement(71000L,1,"let mut head_line = Line::from_iter(vec!["));
		sList.add(new Statement(72000L,2,"(Point::new(Mm(10.0), Mm(neat_height)), false),"));
		sList.add(new Statement(73000L,2,"(Point::new(Mm(neat_width+10.0), Mm(neat_height)), false)]);"));
		sList.add(new Statement(74000L,1,"head_line.set_stroke(true);"));
		sList.add(new Statement(75000L,1,"layer.set_outline_color(outline_color);"));
		sList.add(new Statement(76000L,1,"layer.set_outline_thickness(2.0);"));
		sList.add(new Statement(77000L,1,"layer.add_shape(head_line);"));
		sList.add(new Statement(78000L,0,""));
		sList.add(new Statement(79000L,1,"let mut row_inner_head_line = Line::from_iter(vec!["));
		sList.add(new Statement(80000L,2,"(Point::new(Mm(10.0), Mm(neat_height)), false),"));
		sList.add(new Statement(81000L,2,"(Point::new(Mm(10.0), Mm(neat_height-row_height)), false)]);"));
		sList.add(new Statement(82000L,1,"row_inner_head_line.set_stroke(true);"));
		sList.add(new Statement(83000L,1,"layer.set_outline_color(innerline_color.clone());"));
		sList.add(new Statement(84000L,1,"layer.set_outline_thickness(2.0);"));
		sList.add(new Statement(85000L,1,"layer.add_shape(row_inner_head_line);"));
		sList.add(new Statement(86000L,1,"let mut col_index = 1.0;"));
		sList.add(new Statement(87000L,1,"for item in headers {"));
		sList.add(new Statement(88000L,2,"let mut row_inner_line = Line::from_iter(vec!["));
		sList.add(new Statement(89000L,3,"(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height)), false),"));
		sList.add(new Statement(90000L,3,"(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height-row_height)), false)]);"));
		sList.add(new Statement(91000L,2,"row_inner_line.set_stroke(true);"));
		sList.add(new Statement(92000L,2,"// layer.set_outline_color(innerline_color.clone());"));
		sList.add(new Statement(93000L,2,"layer.begin_text_section();"));
		sList.add(new Statement(94000L,2,"layer.set_outline_thickness(1.0);"));
		sList.add(new Statement(95000L,2,"layer.add_shape(row_inner_line);"));
		sList.add(new Statement(96000L,2,"layer.set_font(&font, 12.0);"));
		sList.add(new Statement(97000L,2,"layer.set_text_cursor(Mm(10.0+(col_index-1.0)*col_width+2.0), Mm(neat_height-1.0/3.0*row_height+2.0));"));
		sList.add(new Statement(98000L,2,"layer.set_line_height(row_height);"));
		sList.add(new Statement(99000L,2,"layer.set_word_spacing(col_width);"));
		sList.add(new Statement(100000L,2,"layer.set_character_spacing(1.0);"));
		sList.add(new Statement(101000L,2,"layer.set_text_rendering_mode(TextRenderingMode::Fill);"));
		sList.add(new Statement(102000L,2,"layer.write_text(item,&font);"));
		sList.add(new Statement(103000L,2,"layer.end_text_section();"));
		sList.add(new Statement(104000L,2,"col_index += 1.0;"));
		sList.add(new Statement(105000L,1,"}"));
		sList.add(new Statement(106000L,0,""));
		sList.add(new Statement(107000L,1,"let mut row_bottom_line = Line::from_iter(vec!["));
		sList.add(new Statement(108000L,2,"(Point::new(Mm(10.0), Mm(neat_height-row_height)), false),"));
		sList.add(new Statement(109000L,2,"(Point::new(Mm(neat_width+10.0), Mm(neat_height-row_height)), false)]);"));
		sList.add(new Statement(110000L,1,"row_bottom_line.set_stroke(true);"));
		sList.add(new Statement(111000L,1,"layer.add_shape(row_bottom_line);"));
		sList.add(new Statement(112000L,0,"}"));
		sList.add(new Statement(113000L,0,""));
		sList.add(new Statement(114000L,0,"fn write_content_rows(font:IndirectFontRef,layer:PdfLayerReference, page_width:f64,page_height:f64,contents:Vec<Vec<String>>,is_images:Vec<bool>){"));
		sList.add(new Statement(115000L,1,"let neat_width = page_width - 20.0;"));
		sList.add(new Statement(116000L,1,"let neat_height = page_height - 10.0;"));
		sList.add(new Statement(117000L,1,"let col_width = neat_width/(Vec::len(&contents.get(0).expect(\"Empty contents.\")) as f64);"));
		sList.add(new Statement(118000L,1,"let row_height = (page_height-20.0)/11.0;"));
		sList.add(new Statement(119000L,1,"println!(\"col_width{}:row_height{}\",col_width,row_height);"));
		sList.add(new Statement(120000L,1,"let outline_color = Color::Rgb(Rgb::new(1.0, 0.0, 0.0, None));"));
		sList.add(new Statement(121000L,1,"let innerline_color = Color::Rgb(Rgb::new(0.0, 0.0, 0.0, None));"));
		sList.add(new Statement(122000L,0,""));
		sList.add(new Statement(123000L,1,"let mut row_index = 1.0;"));
		sList.add(new Statement(124000L,1,"for row in contents{"));
		sList.add(new Statement(125000L,2,"let mut row_inner_head_line = Line::from_iter(vec!["));
		sList.add(new Statement(126000L,3,"(Point::new(Mm(10.0), Mm(neat_height-row_index*row_height)), false),"));
		sList.add(new Statement(127000L,3,"(Point::new(Mm(10.0), Mm(neat_height-(row_index+1.0)*row_height)), false)]);"));
		sList.add(new Statement(128000L,2,"row_inner_head_line.set_stroke(true);"));
		sList.add(new Statement(129000L,2,"layer.set_outline_color(innerline_color.clone());"));
		sList.add(new Statement(130000L,2,"layer.set_outline_thickness(2.0);"));
		sList.add(new Statement(131000L,2,"layer.add_shape(row_inner_head_line);"));
		sList.add(new Statement(132000L,2,"let mut col_index = 1.0;"));
		sList.add(new Statement(133000L,2,"for item in row {"));
		sList.add(new Statement(134000L,3,"let mut row_inner_line = Line::from_iter(vec!["));
		sList.add(new Statement(135000L,4,"(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height-row_index*row_height)), false),"));
		sList.add(new Statement(136000L,4,"(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height-(row_index+1.0)*row_height)), false)]);"));
		sList.add(new Statement(137000L,3,"row_inner_line.set_stroke(true);"));
		sList.add(new Statement(138000L,3,"// layer.set_outline_color(innerline_color.clone());"));
		sList.add(new Statement(139000L,3,"layer.begin_text_section();"));
		sList.add(new Statement(140000L,3,"layer.set_outline_thickness(1.0);"));
		sList.add(new Statement(141000L,3,"layer.add_shape(row_inner_line);"));
		sList.add(new Statement(142000L,3,"layer.set_font(&font, 12.0);"));
		sList.add(new Statement(143000L,3,"layer.set_text_cursor(Mm(10.0+(col_index-1.0)*col_width+2.0), Mm(neat_height-1.0/3.0*row_height+2.0-row_index*row_height));"));
		sList.add(new Statement(144000L,3,"layer.set_line_height(row_height);"));
		sList.add(new Statement(145000L,3,"layer.set_word_spacing(col_width);"));
		sList.add(new Statement(146000L,3,"layer.set_character_spacing(1.0);"));
		sList.add(new Statement(147000L,3,"layer.set_text_rendering_mode(TextRenderingMode::Fill);"));
		sList.add(new Statement(148000L,3,"if *(is_images.get((col_index -1.0) as usize).expect(\"IsImages is none.\")){"));
		sList.add(new Statement(149000L,4,"if item == \"\" || item.len() == 0 {"));
		sList.add(new Statement(150000L,5,"layer.write_text(\"\".to_string(),&font);"));
		sList.add(new Statement(151000L,4,"}else{"));
		sList.add(new Statement(152000L,5,"let img = get_image(item);"));
		sList.add(new Statement(153000L,5,"match img {"));
		sList.add(new Statement(154000L,6,"Some(img) => {"));
		sList.add(new Statement(155000L,7,"let mut img_t_form = ImageTransform::default();"));
		sList.add(new Statement(156000L,7,"let width = img.image.width.0 as f64 ;"));
		sList.add(new Statement(157000L,7,"let height = img.image.height.0 as f64;"));
		sList.add(new Statement(158000L,7,"let dpi = 30.0/2.54;"));
		sList.add(new Statement(159000L,7,"let ratio = row_height / height * dpi;"));
		sList.add(new Statement(160000L,7,""));
		sList.add(new Statement(161000L,7,"img_t_form.translate_x = Some(Mm(10.0+(col_index-1.0)*col_width+2.0));"));
		sList.add(new Statement(162000L,7,"img_t_form.translate_y = Some(Mm(neat_height-row_height-row_index*row_height));"));
		sList.add(new Statement(163000L,7,"img_t_form.scale_x = Some(ratio);"));
		sList.add(new Statement(164000L,7,"img_t_form.scale_y = Some(ratio);"));
		sList.add(new Statement(165000L,7,"img_t_form.dpi = Some(300.0);"));
		sList.add(new Statement(166000L,7,"img.add_to_layer(layer.clone(), img_t_form);"));
		sList.add(new Statement(167000L,6,"},"));
		sList.add(new Statement(168000L,6,"None => {"));
		sList.add(new Statement(169000L,7,"layer.write_text(\"\".to_string(),&font);"));
		sList.add(new Statement(170000L,6,"}"));
		sList.add(new Statement(171000L,5,"}"));
		sList.add(new Statement(172000L,4,"}"));
		sList.add(new Statement(173000L,3,"}else {"));
		sList.add(new Statement(174000L,4,"layer.write_text(item,&font);"));
		sList.add(new Statement(175000L,3,"}"));
		sList.add(new Statement(176000L,3,"layer.end_text_section();"));
		sList.add(new Statement(177000L,3,"col_index += 1.0;"));
		sList.add(new Statement(178000L,2,"}"));
		sList.add(new Statement(179000L,0,""));
		sList.add(new Statement(180000L,2,"let mut row_bottom_line = Line::from_iter(vec!["));
		sList.add(new Statement(181000L,3,"(Point::new(Mm(10.0), Mm(neat_height- (row_index+1.0)*row_height)), false),"));
		sList.add(new Statement(182000L,3,"(Point::new(Mm(neat_width+10.0), Mm(neat_height-(row_index+1.0)*row_height)), false)]);"));
		sList.add(new Statement(183000L,2,"row_bottom_line.set_stroke(true);"));
		sList.add(new Statement(184000L,2,"layer.add_shape(row_bottom_line);"));
		sList.add(new Statement(185000L,2,"row_index += 1.0;"));
		sList.add(new Statement(186000L,1,"}"));
		sList.add(new Statement(187000L,0,"}"));
		sList.add(new Statement(188000L,0,""));
		sList.add(new Statement(189000L,0,"fn get_image(data:String)->Option<Image>{"));
		sList.add(new Statement(190000L,1,"println!(\"{}\",&data.clone());"));
		sList.add(new Statement(191000L,1,"let image_data = base64::decode(data.clone());"));
		sList.add(new Statement(192000L,1,""));
		sList.add(new Statement(193000L,1,"match image_data {"));
		sList.add(new Statement(194000L,2,"Err(e) => {"));
		sList.add(new Statement(195000L,3,"println!(\"error:{}\",e);"));
		sList.add(new Statement(196000L,3,"println!(\"imageLength:{}\",String::len(&data.clone()));"));
		sList.add(new Statement(197000L,3,"None"));
		sList.add(new Statement(198000L,2,"},"));
		sList.add(new Statement(199000L,2,"Ok(image_data) => {"));
		sList.add(new Statement(200000L,3,"let img=image::load_from_memory(&image_data).unwrap();"));
		sList.add(new Statement(201000L,3,"let image = Image::from_dynamic_image(&img);"));
		sList.add(new Statement(202000L,3,"Some(image)"));
		sList.add(new Statement(203000L,2,"}"));
		sList.add(new Statement(204000L,1,"}"));
		sList.add(new Statement(205000L,0,"}"));

		return WriteableUtil.merge(sList);
	}
}
